package com.bonc.excel.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.logging.log4j.util.PropertiesUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.Map.Entry;

/**
 * 自定义工具
 */
public class JSONUtil {
    private static Logger logger = LoggerFactory.getLogger(JSONUtil.class);
    private static HashMap<String, String> resultCodeMap;

    public static Map<String, Object> dealJsonParam(String s) {
        logger.info("JsonParam:\t{}", s);
        return JSONObject.toJavaObject(JSON.parseObject(s), Map.class);
    }

    public static Map<String, Object> dealJsonParam1(String s) {

        return JSONObject.toJavaObject(JSON.parseObject(s), Map.class);
    }


    public static boolean checkJsonParam(Map<String, Object> map, Set<String> set) {
        return map.keySet().containsAll(set);
    }

    public static boolean checkJsonParam(Map<String, Object> map, String param) {
        HashSet<String> set = new HashSet<>();
        for (String str : param.split(",")){
            set.add(str);
        }
        return map.keySet().containsAll(set);
    }

    public static JSONObject getExceptionJSONObject(String resultCode) {
        JSONObject o = new JSONObject();
        o.put("resultCode", resultCode);
        return o;
    }


    public static String getResponse(JSONArray a) {
        return toJson(a);
    }

    public static String getResponse(JSONObject a) {
        if (a.containsKey("resultCode")){
            return toExceptionJson(a);
        }
        return toJson(a);
    }

    public static String toJson(Object a) {
        JSONObject o = new JSONObject();
        o.put("resultCode", "0000");
        o.put("resultDesc", "");
        o.put("resultData", a);
        return o.toJSONString();
    }

    private static String toExceptionJson(JSONObject a) {
        JSONObject o = a;
        o.put("resultDesc", resultCodeMap.get(o.get("resultCode")));
        o.put("resultData", "");
        return o.toJSONString();
    }

    public static List<String> stringToList(String strs) {
        String str[] = strs.split(",");
        return Arrays.asList(str);
    }

    public static Object textToJson(String text) {
        Object objectJson = JSON.parse(text);
        return objectJson;
    }

    public static HashMap stringToHashMap(String s) {
        Map m = JSONObject.parseObject(s);
        HashMap<String, String> returnMap = new HashMap<String, String>();
        for (Object o : m.entrySet()) {
            Entry entry = (Entry) o;
            returnMap.put(String.valueOf(entry.getKey()), String.valueOf(entry.getValue()));
        }
        return returnMap;
    }

    static {
        resultCodeMap = new HashMap<>();
        Properties p = new Properties();
        InputStream i = PropertiesUtil.class.getClassLoader().getResourceAsStream("result-code.properties");
        try {
            p.load(i);
            for (Object key : p.keySet()){
                resultCodeMap.put(key.toString(), p.get(key).toString());
            }
        } catch (IOException e) {
            logger.debug(e.toString());
        }finally {
            try {
                if(i!=null){
                    i.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 将map转化为string
     *
     * @param m
     * @return getResponse
     */
    public static String collectToString(Map m) {
        String s = JSONObject.toJSONString(m);
        return s;
    }

    /**
     * json字符串转化为map
     *
     * @param s
     * @return
     */
    public static Map stringToCollect(String s) {
        Map m = JSONObject.parseObject(s);
        return m;
    }

    public static String ok(Object data) {
        JSONObject o = new JSONObject();
        o.put("resultCode", "0000");
        o.put("resultDesc", "success");
        o.put("resultData", data);
        return o.toJSONString();
    }

    /**
     * 这个方法关闭了fastJson的循环引用检测
     * <p>
     * 当序列化后的JSON传输到浏览器或者其他语言中，这些json解析器不支持循环引用，会导致数据丢失。
     * 当出现<code>{“$ref”:”\$”} </code> 异常或者乱码时，请使用此方法.
     * <p>
     * 关闭循环引用检测功能后，在序列化的时候会可能出现StackOverFlow异常,
     * 这时需要用户处理好属性之间是否有循环引用的情况出现：
     * 可以在字段或者getter方法上使用@JSONField(serialize=false)注解来设置某些域不进行序列化，
     * 从而避免循环引用的情况发生。
     *
     * @param data 数据体
     * @return 格式化后数据
     */
    public static String success(Object data) {
        JSONObject o = new JSONObject();
        o.put("resultCode", "0000");
        o.put("resultDesc", "success");
        o.put("resultData", data);
        return JSON.toJSONString(o, SerializerFeature.DisableCircularReferenceDetect);
    }

    public static String error(String resultDesc) {
        JSONObject o = new JSONObject();
        o.put("resultCode", "0001");
        o.put("resultDesc", resultDesc);
        return o.toJSONString();
    }

    public static String error(String resultDesc,Object data) {
        JSONObject o = new JSONObject();
        o.put("resultCode", "0001");
        o.put("resultDesc", resultDesc);
        o.put("resultData", data);
        return o.toJSONString();
    }
}